package com.rightsidetech.mall.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.rightsidetech.commom.base.DelReq;
import com.rightsidetech.commom.base.ResponseData;
import com.rightsidetech.commom.enums.CodeIdEnum;
import com.rightsidetech.commom.utils.BeanValidator;
import com.rightsidetech.mall.dto.request.*;
import com.rightsidetech.mall.dto.request.storeApp.StoreIntegralReq;
import com.rightsidetech.mall.dto.response.IntegralDetailResp;
import com.rightsidetech.mall.dto.response.IntegralPageResp;
import com.rightsidetech.mall.dto.response.storeApp.StoreIntegralResp;
import com.rightsidetech.mall.entity.*;
import com.rightsidetech.mall.mapper.MallBaseInfoMapper;
import com.rightsidetech.mall.mapper.MallCommodityAuditRecordMapper;
import com.rightsidetech.mall.mapper.MallIntegralCommodityMapper;
import com.rightsidetech.mall.mapper.MallTypeMapper;
import com.rightsidetech.mall.service.MallIntegralCommodityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service("mallIntegralCommodityService")
public class MallIntegralCommodityServiceImpl implements MallIntegralCommodityService {

    @Resource
    private MallBaseInfoMapper mallBaseInfoMapper;
    @Resource
    private MallIntegralCommodityMapper mallIntegralCommodityMapper;
    @Resource
    private MallCommodityAuditRecordMapper mallCommodityAuditRecordMapper;
    @Resource
    private MallTypeMapper mallTypeMapper;

    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    private TransactionDefinition transactionDefinition;


    @Override
    public ResponseData saveIntegral(IntegralSaveReq req,String createrName,Long createrId) {
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        MallBaseInfoWithBLOBs baseInfo = mallBaseInfoMapper.selectByPrimaryKey(req.getMallBaseId());
        if(ObjectUtil.isEmpty(baseInfo)){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"未找到基础商品");
        }
        DetailSpecsReq specs1 = req.getSpecs();
        if(ObjectUtil.isEmpty(specs1)){
            if(StrUtil.isNotEmpty(baseInfo.getSpecsJson())){
                return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"基础商品维护过规格,请选择规格后创建积分商品");
            }
            Long count = mallIntegralCommodityMapper.selectCountByBaseIdAndSpecs(baseInfo.getId(),null);
            if(count > 0){
                return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"此基础商品已经维护过积分商城商品");
            }
            MallIntegralCommodity commodity = getMallIntegralCommodity(req, baseInfo, createrName, createrId);
//            commodity.setSpecsCode("000");
            if (mallIntegralCommodityMapper.insertSelective(commodity) <= 0) {
                return ResponseData.fail("添加失败");
            }
            return ResponseData.success(CodeIdEnum.Success);
        }
        ConstraintViolation validate1 = BeanValidator.validate(specs1);
        if (validate1 != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate1.getMessage());
        }
        if(StrUtil.isEmpty(baseInfo.getSpecsJson())){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"基础商品维护没有维护过规格,添加时不允许有规格");
        }
        ResponseData check = checkSpesc(specs1);
        if(ObjectUtil.isNotEmpty(check)){
            return check;
        }
        String specs = req.getSpecs().getValueList().stream().map(DetailSpecsValueReq::getSpecsValue).collect(Collectors.joining("、"));
        Long count = mallIntegralCommodityMapper.selectCountByBaseIdAndSpecs(baseInfo.getId(),specs);
        if(count > 0){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"此规格已经维护过积分商品");
        }
        MallIntegralCommodity commodity = getMallIntegralCommodity(req, baseInfo, createrName, createrId);
        commodity.setSpecsCode(req.getSpecs().getCode());
        commodity.setSpecs(specs);
        commodity.setSpecsJson(JSONUtil.toJsonStr(specs1));
        if (mallIntegralCommodityMapper.insertSelective(commodity) <= 0) {
            return ResponseData.fail("添加失败");
        }
        return ResponseData.success(CodeIdEnum.Success);
    }

    private MallIntegralCommodity getMallIntegralCommodity(IntegralSaveReq req,MallBaseInfoWithBLOBs baseInfo,String createrName,Long createrId){
        MallIntegralCommodity commodity = new MallIntegralCommodity();
        commodity.setBaseInfoId(req.getMallBaseId());
        commodity.setPrice(req.getPrice());
        commodity.setUnderlinedPrice(req.getUnderlinedPrice());
        commodity.setCommodityStatus((byte)0);
        commodity.setCommodityName(baseInfo.getCommodityName());
        commodity.setStock(req.getStock());
        commodity.setCode(baseInfo.getCode());
        commodity.setIsPopular((byte)0);
        commodity.setBrandId(baseInfo.getBrandId());
        commodity.setTypeId(baseInfo.getTypeId());
        commodity.setCover(req.getCover());
        commodity.setCreatedAt(new Date());
        commodity.setCreaterName(createrName);
        commodity.setCreaterId(createrId);
        return commodity;
    }

    @Override
    public ResponseData updateIntegral(IntegralUpReq req, String updaterName, Long updaterId) {
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        MallIntegralCommodity commodity = mallIntegralCommodityMapper.selectByPrimaryKey(req.getId());
        if(ObjectUtil.isEmpty(commodity)){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"未找到需要操作的数据");
        }
        if(commodity.getCommodityStatus() == 1){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"商品待审核不允许修改");
        }
        if (commodity.getCommodityStatus() == 3) {
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"此商品已上架不允许修改");
        }
        if(ObjectUtil.isEmpty(commodity)){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"未找到积分商品");
        }
        DetailSpecsReq specs = req.getSpecs();
        if(ObjectUtil.isNotEmpty(specs)){
            return upIntegral(req,commodity,updaterName,updaterId);
        }
        MallBaseInfoWithBLOBs info = mallBaseInfoMapper.selectByPrimaryKey(commodity.getBaseInfoId());
        if(ObjectUtil.isEmpty(info)){
            return ResponseData.fail("未找到基础商品");
        }
        if(StrUtil.isNotBlank(info.getSpecsJson())){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"此基础商品有规格请选择规格后修改商品");
        }
        commodity = new MallIntegralCommodity();
        commodity.setId(req.getId());
        commodity.setBaseInfoId(info.getId());
        commodity.setPrice(req.getPrice());
        commodity.setUnderlinedPrice(req.getUnderlinedPrice());
        commodity.setCommodityStatus((byte)0);
        commodity.setCommodityName(info.getCommodityName());
        commodity.setStock(req.getStock());
        commodity.setCode(info.getCode());
//        commodity.setSpecsCode("000");
        commodity.setBrandId(info.getBrandId());
        commodity.setTypeId(info.getTypeId());
        commodity.setCover(req.getCover());
        commodity.setUpdaterId(updaterId);
        commodity.setUpdaterName(updaterName);
        commodity.setUpdatedAt(new Date());
        if (mallIntegralCommodityMapper.updateById(commodity) <= 0) {
            return ResponseData.fail("更新失败");
        }
        return ResponseData.success(CodeIdEnum.Success);
    }

    private ResponseData checkSpesc(DetailSpecsReq specs){
        List<DetailSpecsValueReq> valueList = specs.getValueList();
        List<DetailSpecsNameReq> nameList = specs.getNameList();
        if(nameList.size() != valueList.size()){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"规格名称与规格值数量不一致");
        }
        for (int i = 0; i < valueList.size(); i++) {
            DetailSpecsNameReq nameReq = nameList.get(i);
            DetailSpecsValueReq valueReq = valueList.get(i);
            ConstraintViolation validate1 = BeanValidator.validate(nameReq);
            if (validate1 != null) {
                return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate1.getMessage());
            }
            ConstraintViolation validate2 = BeanValidator.validate(valueReq);
            if (validate2 != null) {
                return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate2.getMessage());
            }
        }
        return null;
    }

    private ResponseData upIntegral(IntegralUpReq req, MallIntegralCommodity commodity, String updaterName, Long updaterId) {
        DetailSpecsReq specs = req.getSpecs();
        ConstraintViolation validate = BeanValidator.validate(specs);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        ResponseData data = checkSpesc(specs);
        if(ObjectUtil.isNotEmpty(data)){
            return data;
        }
        MallBaseInfoWithBLOBs info = mallBaseInfoMapper.selectByPrimaryKey(commodity.getBaseInfoId());
        if(ObjectUtil.isEmpty(info)){
            return ResponseData.fail("未找到基础商品");
        }
        String collect = specs.getValueList().stream().map(DetailSpecsValueReq::getSpecsValue).collect(Collectors.joining("、"));
        if(!collect.equals(commodity.getSpecs())){
            Long count = mallIntegralCommodityMapper.selectCountByBaseIdAndSpecs(info.getId(), collect);
            if(count > 0){
                return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"此基础商品该规格已经维护过基础商品");
            }
        }
        commodity = new MallIntegralCommodity();
        commodity.setId(req.getId());
        commodity.setCover(req.getCover());
        commodity.setUpdatedAt(new Date());
        commodity.setUpdaterId(updaterId);
        commodity.setUpdaterName(updaterName);
        commodity.setUnderlinedPrice(req.getUnderlinedPrice());
        commodity.setPrice(req.getPrice());
        commodity.setStock(req.getStock());
        commodity.setCommodityStatus((byte)0);
        commodity.setSpecsJson(JSONUtil.toJsonStr(specs));
        commodity.setCommodityName(info.getCommodityName());
        commodity.setCode(info.getCode());
        commodity.setSpecsCode(specs.getCode());
        commodity.setTypeId(info.getTypeId());
        commodity.setBrandId(info.getBrandId());
        commodity.setSpecs(collect);
        if (mallIntegralCommodityMapper.updateByPrimaryKeySelective(commodity) <= 0) {
            return ResponseData.fail("更新失败");
        }
        return ResponseData.success(CodeIdEnum.Success);
    }

    @Override
    public ResponseData<PageInfo<IntegralPageResp>> page(IntegralPageReq req) {
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        PageHelper.startPage(req.getPageNo(),req.getPageSize());
        List<IntegralPageResp> result = mallIntegralCommodityMapper.selectPageList(req);
        return ResponseData.success(new PageInfo<>(result));
    }

    @Override
    public ResponseData arraignment(DelReq req) {
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        MallIntegralCommodity commodity = mallIntegralCommodityMapper.selectByPrimaryKey(req.getId());
        if(ObjectUtil.isEmpty(commodity)){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "未找到需要提审的商品");
        }
        if(commodity.getCommodityStatus() != 0){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "商品状态不正确");
        }
        commodity = new MallIntegralCommodity();
        commodity.setId(req.getId());
        commodity.setCommodityStatus((byte)1);
        if (mallIntegralCommodityMapper.updateByPrimaryKeySelective(commodity) <= 0) {
            return ResponseData.fail("提审失败");
        }
        return ResponseData.success(CodeIdEnum.Success);
    }

    @Override
    public ResponseData verify(VerifyCommodityReq req, String createrName, Long createrId) {
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        MallIntegralCommodity commodity = mallIntegralCommodityMapper.selectByPrimaryKey(req.getId());
        if(ObjectUtil.isEmpty(commodity)){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "未找到需要审核的商品");
        }
        if(commodity.getCommodityStatus() != 1){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "商品状态不正确");
        }
        TransactionStatus transaction = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try {
            if(req.getStatus() == 1){
                if(StrUtil.isBlank(req.getAuditContent())){
                    dataSourceTransactionManager.rollback(transaction);
                    return ResponseData.fail("驳回需要填写驳回理由");
                }
                MallCommodityAuditRecord record = getRecord(commodity, createrName, createrId);
                record.setAuditContent(req.getAuditContent());
                record.setAuditStatus((byte)-1);
                if (mallCommodityAuditRecordMapper.insertSelective(record) <= 0) {
                    dataSourceTransactionManager.rollback(transaction);
                    return ResponseData.fail("审核失败");
                }
                MallIntegralCommodity integralCommodity = new MallIntegralCommodity();
                integralCommodity.setId(req.getId());
                integralCommodity.setCommodityStatus((byte)-1);
                if(commodity.getCommoditySort() == null){
                    Long sort = mallIntegralCommodityMapper.selectSortOne();
                    if(sort == null){
                        integralCommodity.setCommoditySort(1L);
                    }else {
                        integralCommodity.setCommoditySort(sort);
                    }
                }
                if(mallIntegralCommodityMapper.updateByPrimaryKeySelective(integralCommodity) <= 0){
                    dataSourceTransactionManager.rollback(transaction);
                    return ResponseData.fail("审核失败");
                }
                dataSourceTransactionManager.commit(transaction);
                return ResponseData.success(CodeIdEnum.Success);
            }
            MallCommodityAuditRecord record = getRecord(commodity, createrName, createrId);
            record.setAuditStatus((byte)1);
            record.setAuditContent(req.getAuditContent());
            if (mallCommodityAuditRecordMapper.insertSelective(record) <= 0) {
                return ResponseData.fail("审核失败");
            }
            commodity = new MallIntegralCommodity();
            commodity.setId(req.getId());
            commodity.setCommodityStatus((byte)2);
            if(mallIntegralCommodityMapper.updateByPrimaryKeySelective(commodity) <= 0){
                dataSourceTransactionManager.rollback(transaction);
                return ResponseData.fail("审核失败");
            }
        }catch (Exception e){
            dataSourceTransactionManager.rollback(transaction);
            return ResponseData.fail("审核失败");
        }
        dataSourceTransactionManager.commit(transaction);
        return ResponseData.success(CodeIdEnum.Success);
    }

    private MallCommodityAuditRecord getRecord(MallIntegralCommodity commodity, String createrName, Long createrId){
        MallCommodityAuditRecord record = new MallCommodityAuditRecord();
        record.setCommodityId(commodity.getId());
        record.setCreatedName(createrName);
        record.setCreatedAt(new Date());
        record.setCreaterId(createrId);
        record.setCommodityMarketName("积分商城");
        record.setCommodityName(commodity.getCommodityName());
        return record;
    }

    @Override
    public ResponseData grounding(CommodityIsGroundingReq req) {
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        MallIntegralCommodity commodity = mallIntegralCommodityMapper.selectByPrimaryKey(req.getId());
        if(ObjectUtil.isEmpty(commodity)){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "未找到需要操作的商品");
        }
        if(commodity.getCommodityStatus() == -1 || commodity.getCommodityStatus() == 0 || commodity.getCommodityStatus() == 1){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "商品状态不正确");
        }
        Byte status = commodity.getCommodityStatus();
        commodity = new MallIntegralCommodity();
        commodity.setId(req.getId());
        if(req.getStatus() == 1){
            if(status == 3){
                return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "此商品已是上架中");
            }
            commodity.setCommodityStatus((byte)3);
        }else {
            if(status == -2){
                return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "此商品已下架");
            }
            if(status == 2){
                return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "待上架商品无需下架");
            }
            commodity.setCommodityStatus((byte)-2);
        }
        if (mallIntegralCommodityMapper.updateByPrimaryKeySelective(commodity) <= 0) {
            return ResponseData.fail("操作失败");
        }
        return ResponseData.success(CodeIdEnum.Success);
    }

    @Override
    public ResponseData sort(CommoditySortReq req) {
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        List<Long> commodityIds = req.getCommodityId();
        List<Long> sorts = req.getSort();
        if(commodityIds.size() != sorts.size()){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"id与排序数量不一致");
        }
        List<MallIntegralCommodity> commoditys = mallIntegralCommodityMapper.selectByIds(commodityIds);
        if(CollUtil.isEmpty(commoditys)){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"未找到商品");
        }
        if(commodityIds.size() != commoditys.size()){
            return ResponseData.fail("有未找到商品的id");
        }
        for (MallIntegralCommodity commodity : commoditys) {
            if(commodity.getCommodityStatus() == -1 || commodity.getCommodityStatus() == 0 || commodity.getCommodityStatus() == 1){
                return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "商品状态不正确");
            }
        }
        for (int i = 0; i < commodityIds.size(); i++) {
            Long id = commodityIds.get(i);
            Long sort = sorts.get(i);
            if(Long.valueOf(0).equals(sort) || sort < 0){
                sort = null;
            }
            if (mallIntegralCommodityMapper.updateSortById(id,sort) <= 0) {
                return ResponseData.fail("操作失败");
            }
        }
        return ResponseData.success(CodeIdEnum.Success);
    }

    @Override
    public ResponseData<PageInfo<StoreIntegralResp>> storePage(StoreIntegralReq req) {
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        PageHelper.startPage(req.getPageNo(),req.getPageSize());
        List<StoreIntegralResp> result = mallIntegralCommodityMapper.selectStorePage(req);
        return ResponseData.success(new PageInfo<>(result));
    }

    @Override
    public ResponseData<IntegralDetailResp> detail(Long id) {
        if(ObjectUtil.isEmpty(id)){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"id不可为空");
        }
        IntegralDetailResp result = mallIntegralCommodityMapper.selectDetail(id);
        if(ObjectUtil.isEmpty(result)){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"未找到该积分商品");
        }
        MallType mallType = mallTypeMapper.selectByPrimaryKey(result.getTypeId());
        List<Long> typeIds = new ArrayList<>();
        typeIds.add(result.getTypeId());
        if (mallType != null) {
            String typeName = mallType.getTypeName();
            while (mallType.getParentId() != 0) {
                MallType type = mallTypeMapper.selectByPrimaryKey(mallType.getParentId());
                typeIds.add(type.getId());
                String prentName = type.getTypeName();
                typeName = prentName + "/" + typeName;
                mallType = type;
            }
            result.setTypeName(typeName);
        }
        result.setTypeIds(typeIds);
        if(result.getCommodityStatus() == -1){
           String AuditContent =  mallCommodityAuditRecordMapper.selectAuditContentByCommodityId(result.getId(),"积分商城");
            result.setAuditContent(AuditContent);
        }
        if(StrUtil.isNotEmpty(result.getSpecsJson())){
            result.setSpecs(JSONUtil.toBean(result.getSpecsJson(),DetailSpecsReq.class));
        }
        return ResponseData.success(result);
    }

    @Override
    public ResponseData popular(CommodityPopularReq req) {
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        MallIntegralCommodity commodity = mallIntegralCommodityMapper.selectByPrimaryKey(req.getId());
        if(ObjectUtil.isEmpty(commodity)){
            return ResponseData.fail("未找到需要操作的商品");
        }
        if(commodity.getIsPopular().equals(req.getIsPopular())){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"此商品已经设置为爆款或非爆款");
        }
        if (commodity.getCommodityStatus() != 2 && commodity.getCommodityStatus() != 3 ){
            return ResponseData.fail("待上架和上架中状态才可以设置爆款");
        }
        commodity = new MallIntegralCommodity();
        commodity.setId(req.getId());
        commodity.setIsPopular(req.getIsPopular());
        if (mallIntegralCommodityMapper.updateByPrimaryKeySelective(commodity) <= 0) {
            return ResponseData.fail("设置失败");
        }
        return ResponseData.success(CodeIdEnum.Success);
    }

    @Override
    public MallIntegralCommodity selectByPrimaryKey(Long id) {
        return mallIntegralCommodityMapper.selectByPrimaryKey(id);
    }

    @Override
    public int updateByPrimaryKeySelective(MallIntegralCommodity record) {
        return mallIntegralCommodityMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public ResponseData<List<IntegralPageResp>> selectList(IntegralPageReq req) {
        return ResponseData.success(mallIntegralCommodityMapper.selectPageList(req));
    }
}
